package com.mxx.common.redis;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mxx.common.conv.CustomObjectMapper;
import com.mxx.common.conv.JacksonConverter;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.data.redis.serializer.GenericToStringSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * @Author itzgyw
 * @Date 2020-01-14
 * @Time 12:26
 * @Description:
 */
public class RedisSerializerFactory {

    public static StringRedisSerializer getStringRedisSerializer() {
        return new StringRedisSerializer();
    }

    public static JdkSerializationRedisSerializer getJdkSerializationRedisSerializer() {
        return new JdkSerializationRedisSerializer();
    }

    public static <T> GenericToStringSerializer<T> getJdkSerializationRedisSerializer(Class<T> classes) {
        return getJdkSerializationRedisSerializer(classes, null);
    }

    public static <T> GenericToStringSerializer<T> getJdkSerializationRedisSerializer(Class<T> classes, ConversionService conversionService) {
        GenericToStringSerializer<T> genericToStringSerializer = new GenericToStringSerializer<>(classes);
        if (conversionService != null) {
            genericToStringSerializer.setConversionService(conversionService);
        } else {
            genericToStringSerializer.setConversionService(DefaultConversionService.getSharedInstance());
        }
        return genericToStringSerializer;
    }

    public static <T> Jackson2JsonRedisSerializer<T> getJackson2JsonRedisSerializer(Class<T> classes) {
        Jackson2JsonRedisSerializer<T> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(classes);
        ObjectMapper objectMapper = new CustomObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        return jackson2JsonRedisSerializer;
    }

    public static <T> Jackson2JsonRedisSerializer<T> getJackson2JsonRedisSerializer(TypeReference<T> tTypeReference) {
        ObjectMapper objectMapper = new CustomObjectMapper();
        JavaType javaType = objectMapper.getTypeFactory().constructType(tTypeReference);
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        Jackson2JsonRedisSerializer<T> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(javaType);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        return jackson2JsonRedisSerializer;
    }
}
